<template>
  <el-dialog
    v-model="dialogVisible"
    title="更换头像"
    width="500px"
    center
    :close-on-click-modal="false"
    @close="handleClose"
  >
    <div class="avatar-upload-content">
      <!-- 当前头像预览 -->
      <div class="current-avatar">
        <h4>当前头像</h4>
        <el-avatar
          :size="100"
          :src="formatAvatarUrl(props.currentAvatar)"
          :icon="UserFilled"
        />
      </div>

      <!-- 上传区域 -->
      <div class="upload-section">
        <h4>选择新头像</h4>
        <el-upload
          ref="uploadRef"
          class="avatar-uploader-container"
          :auto-upload="false"
          :show-file-list="false"
          :on-change="handleFileChange"
          :disabled="uploading"
          accept="image/jpeg,image/jpg,image/png,image/gif,image/webp"
        >
          <div class="avatar-wrapper" :class="{ uploading: uploading }">
            <el-image
              v-if="previewUrl && !uploading"
              :src="previewUrl"
              class="avatar-image"
              fit="cover"
              :preview-src-list="[previewUrl]"
              :initial-index="0"
              preview-teleported
            >
              <template #error>
                <div class="avatar-placeholder">
                  <el-icon><Picture /></el-icon>
                  <span>预览</span>
                </div>
              </template>
            </el-image>

            <div v-else-if="uploading" class="avatar-uploading">
              <el-icon class="uploading-icon"><Loading /></el-icon>
              <span>上传中...</span>
            </div>

            <div v-else class="avatar-placeholder">
              <el-icon><Plus /></el-icon>
              <span>点击或拖拽图片到此处上传</span>
              <p class="upload-hint">
                支持 JPG、PNG、GIF、WebP 格式，文件大小不超过 5MB
              </p>
            </div>
          </div>
        </el-upload>
      </div>

      <!-- 上传进度 -->
      <div v-if="uploading" class="upload-progress">
        <el-progress :percentage="uploadProgress" :show-text="false" />
        <p>上传中... {{ uploadProgress }}%</p>
      </div>
    </div>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleClose">取消</el-button>
        <el-button
          type="primary"
          :loading="uploading"
          :disabled="!selectedFile"
          @click="handleConfirm"
        >
          确认上传
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, computed, watch } from "vue";
import { ElMessage } from "element-plus";
import { Plus, Picture, Loading, UserFilled } from "@element-plus/icons-vue";
import {
  uploadAvatarApi,
  validateImageFile,
  validateFileSize,
  formatErrorMessage
} from "@/api/user-profile-update";

interface Props {
  visible: boolean;
  currentAvatar?: string;
}

interface Emits {
  (e: "update:visible", value: boolean): void;
  (e: "success", avatarUrl: string): void;
}

const props = withDefaults(defineProps<Props>(), {
  currentAvatar: ""
});

const emit = defineEmits<Emits>();

// 格式化头像URL
const formatAvatarUrl = (url: string): string => {
  if (!url) return "";

  // 如果已经是完整URL，直接返回
  if (url.startsWith("http://") || url.startsWith("https://")) {
    return url;
  }

  // 如果是相对路径，添加基础URL
  const baseURL = import.meta.env.DEV
    ? "http://localhost:8081"
    : "http://localhost:8081";
  return baseURL + url;
};

// 对话框显示状态
const dialogVisible = computed({
  get: () => props.visible,
  set: value => emit("update:visible", value)
});

// 上传相关状态
const uploadRef = ref();
const previewUrl = ref("");
const selectedFile = ref<File | null>(null);
const uploading = ref(false);
const uploadProgress = ref(0);

// 监听对话框关闭，重置状态
watch(dialogVisible, visible => {
  if (!visible) {
    resetUploadState();
  }
});

// 重置上传状态
const resetUploadState = () => {
  if (previewUrl.value && previewUrl.value.startsWith("blob:")) {
    URL.revokeObjectURL(previewUrl.value);
  }
  previewUrl.value = "";
  selectedFile.value = null;
  uploading.value = false;
  uploadProgress.value = 0;
};

// 文件选择处理 (onChange事件)
const handleFileChange = (file: any) => {
  if (file && file.raw) {
    const rawFile = file.raw as File;

    // 验证文件类型
    if (!validateImageFile(rawFile)) {
      ElMessage.error("请选择正确的图片格式（JPG、PNG、GIF、WebP）");
      return;
    }

    // 验证文件大小
    if (!validateFileSize(rawFile, 5)) {
      ElMessage.error("图片大小不能超过 5MB");
      return;
    }

    // 保存选择的文件
    selectedFile.value = rawFile;

    // 创建预览URL
    if (previewUrl.value) {
      URL.revokeObjectURL(previewUrl.value);
    }
    previewUrl.value = URL.createObjectURL(rawFile);
  }
};

// 确认上传
const handleConfirm = async () => {
  if (!selectedFile.value) {
    ElMessage.warning("请先选择图片");
    return;
  }

  try {
    uploading.value = true;
    uploadProgress.value = 0;

    // 模拟上传进度
    const progressInterval = setInterval(() => {
      if (uploadProgress.value < 90) {
        uploadProgress.value += 10;
      }
    }, 200);

    const response = await uploadAvatarApi(selectedFile.value);

    clearInterval(progressInterval);
    uploadProgress.value = 100;

    if (response.code === 200) {
      ElMessage.success("头像上传成功");
      emit("success", response.data.fileUrl);
      handleClose();
    } else {
      ElMessage.error(response.message || "上传失败");
    }
  } catch (error) {
    uploading.value = false;
    uploadProgress.value = 0;
    console.error("头像上传失败:", error);
    ElMessage.error(formatErrorMessage(error));
  } finally {
    uploading.value = false;
  }
};

// 关闭对话框
const handleClose = () => {
  // 清理预览URL
  if (previewUrl.value && previewUrl.value.startsWith("blob:")) {
    URL.revokeObjectURL(previewUrl.value);
  }

  resetUploadState();
  emit("update:visible", false);
};
</script>

<style scoped lang="scss">
.avatar-upload-content {
  padding: 20px;
  text-align: center; /* 整体居中 */

  .current-avatar {
    margin-bottom: 24px;
    text-align: center;

    h4 {
      margin: 0 0 12px;
      font-size: 16px;
      font-weight: 600;
      color: #1f2937;
    }
  }

  .upload-section {
    @keyframes rotate {
      from {
        transform: rotate(0deg);
      }

      to {
        transform: rotate(360deg);
      }
    }
    // 将声明移到嵌套规则之前
    margin-bottom: 24px;
    text-align: center; /* 居中对齐 */

    h4 {
      margin: 0 0 12px;
      font-size: 16px;
      font-weight: 600;
      color: #1f2937;
    }

    .avatar-uploader-container {
      :deep(.el-upload) {
        position: relative;
        overflow: hidden;
        cursor: pointer;
        border: 2px dashed var(--el-border-color);
        border-radius: 8px;
        transition: all 0.3s;

        &:hover {
          border-color: var(--el-color-primary);
        }
      }
    }

    .avatar-wrapper {
      position: relative;
      display: flex;
      align-items: center;
      justify-content: center;
      width: 200px;
      height: 200px;
      margin: 0 auto; /* 水平居中 */

      &.uploading {
        pointer-events: none;
      }
    }

    .avatar-image {
      width: 100%;
      height: 100%;
      border-radius: 6px;
    }

    .avatar-placeholder,
    .avatar-uploading {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      padding: 20px;
      font-size: 14px;
      color: var(--el-text-color-secondary);
      text-align: center;

      .el-icon {
        margin-bottom: 16px;
        font-size: 48px;
      }

      .upload-hint {
        margin-top: 8px;
        font-size: 12px;
        color: var(--el-text-color-placeholder);
      }
    }

    .avatar-uploading {
      .uploading-icon {
        animation: rotate 2s linear infinite;
      }
    }
  }

  .upload-progress {
    margin-bottom: 24px;
    text-align: center;

    p {
      margin: 8px 0 0;
      font-size: 14px;
      color: #6b7280;
    }
  }

  .crop-options {
    h4 {
      margin: 0 0 12px;
      font-size: 16px;
      font-weight: 600;
      color: #1f2937;
    }

    .crop-controls {
      :deep(.el-radio-group) {
        .el-radio {
          margin-right: 16px;
        }
      }
    }
  }
}

.dialog-footer {
  display: flex;
  gap: 12px;
  justify-content: flex-end;
}
</style>
